'use strict';
// 引入
const crypto = require('crypto');
const Controller = require('egg').Controller;

class UserController extends Controller {
    async reg() {
        let { ctx, app } = this;
        // 参数验证
        ctx.validate({
            username: {
                type: 'string',
                required: true,
                range: {
                    min: 5,
                    max: 20
                },
                desc: '用户名'
            },
            password: {
                type: 'string',
                required: true,
                desc: '密码'
            },
            repassword: {
                type: 'string',
                required: true,
                desc: '确认密码'
            }
        }, {
            equals: [
                ['password', 'repassword']
            ]
        });
        let { username, password } = ctx.request.body;
        // 验证用户是否已经存在
        if (await app.model.User.findOne({
            where: {
                username,
            }
        })) {
            ctx.throw(400, '用户名已存在');
        }
        // 创建用户
        let user = await app.model.User.create({
            username,
            password
        });
        if (!user) {
            ctx.throw(400, '创建用户失败');
        }
        ctx.apiSuccess(user);
    }
    // 登录
    async login() {
        const { ctx, app } = this;
        // 参数验证
        ctx.validate({
            username: {
                type: 'string',
                required: true,
                desc: '用户名'
            },
            password: {
                type: 'string',
                required: true,
                desc: '密码'
            },
        });
        let { username, password } = ctx.request.body;
        // 验证该用户是否存在|验证该用户状态是否启用
        let user = await app.model.User.findOne({
            where: {
                username,
            }
        });
        if (!user) {
            ctx.throw(400, '用户不存在或已被禁用');
        }
        // 验证密码
        await this.checkPassword(password, user.password);

        user = JSON.parse(JSON.stringify(user));
        // 生成token
        let token = ctx.getToken(user);
        user.token = token;
        delete user.password;
        // 加入缓存中
        if (!await this.service.cache.set('user_' + user.id, token)) {
            ctx.throw(400, '登录失败');
        }
        // 返回用户信息和token
        return ctx.apiSuccess(user);
    }
    // 退出登录
    async logout() {
        const { ctx, service } = this;
        // 拿到当前用户id
        let current_user_id = ctx.authUser.id;
        // 移除redis当前用户信息
        if (!await service.cache.remove('user_' + current_user_id)) {
            ctx.throw(400, '退出登录失败');
        }
        ctx.apiSuccess('退出成功');
    }

    // 验证密码
    async checkPassword(password, hash_password) {
        // 先对需要验证的密码进行加密
        const hmac = crypto.createHash("sha256", this.app.config.crypto.secret);
        hmac.update(password);
        password = hmac.digest("hex");
        let res = password === hash_password;
        if (!res) {
            this.ctx.throw(400, '密码错误');
        }
        return true;
    }
    // 统计相关数据
    async statistics() {
        const { ctx, service, app } = this;
        let user_id = ctx.authUser.id;

        let followCount = await service.user.getFollowCount(user_id);
        let favaCount=await service.user.getFavaCount(user_id)
        let videoCount = await service.user.getVideoCount(user_id);

        ctx.apiSuccess({
            followCount,
            videoCount,
            favaCount
        });
    }
    // 获取用户相关信息
    async user_info() {
        const { ctx, service, app } = this;
        let currentUser = ctx.authUser;

        ctx.validate({
            user_id: {
                required: true,
                desc: "用户id",
                type: "int"
            }
        });

        let user_id = ctx.query.user_id;

        let res = await service.user.getUserInfo(user_id);

        let fensCount = 0;

        let followCount = 0;

        if (res) {
            fensCount = await service.user.getFensCount(user_id);
            followCount = await service.user.getFollowCount(user_id);
        }

        let follow = false;

        if (currentUser) {
            follow = await service.user.isFollow(currentUser.id, user_id);
        }

        ctx.apiSuccess({
            user: res,
            fensCount,
            followCount,
            follow
        });
    }

    async follow() {
        //   解构
        let {app,ctx,service}=this
        // 获取当前用户
        let currentUser=ctx.authUser
        // 参数验证
        ctx.validate({
            follow_id:{
                type:'int',
                desc:'关注者ID',
                required:true
            }
        })
        // 获取参数
        let {follow_id}=ctx.request.body
        let where={
            user_id:currentUser.id,
            follow_id
        }
        // 判断是否关注用户
        let follow=await app.model.Follow.findOne({where})
        if(follow){
            return ctx.apiFail('你已关注过了')
        }
        // 判断是用户是否存在
        if(!await service.user.exist(follow_id)){
            return ctx.apiFail('用户不存在')
        }
        // 判断用户是否为自己
        if(follow_id===currentUser.id){
            return ctx.apiFail('不能关注自己')
        }
        // 创建关注
        await app.model.Follow.create({...where})
        // 返回数据
        ctx.apiSuccess({status:true,msg:'关注成功'})
        
      }

    //  取消关注
    async unfollow(){
        // 解构
        let {app,ctx,service}=this
        let user_id=ctx.authUser.id
        // 获取用户id
        // 参数验证
        ctx.validate({
            follow_id:{
                type:'int',
                desc:'描述',
                required:true
            }
        })
        // 获取参数
        let {follow_id}=ctx.request.body
        let where={
            user_id,
            follow_id
        }
        // 判断用户是否存在
        if(!await service.user.exist(follow_id)){
            return ctx.apiFail('用户不存在')
        }
        // 判断是否关注
        if(follow_id===user_id){
            return ctx.apiFail('不能取关自己')
        }
        // 判断是否是自己
        let follow=await app.model.Follow.findOne({where})
        if(!follow){
            return ctx.apiFail('你还未关注该用户')
        }
        // 删除该关注
        await follow.destroy()
        // 返回
        ctx.apiSuccess({
            status:false,
            msg:'取消关注成功'
        })
    }


    // 我的关注列表
    async follows(){
      // 解构
      let {ctx,app}=this
      // 获取用户
      let user_id=ctx.authUser.id
      // 查询我的关注列表--关联用户表--分页查询
      let rows=await ctx.page(app.model.Follow,{
            user_id:user_id,
        },{
            include:[{
                model:app.model.User,
                as: "user_follow",
              attributes: ['id', 'username', 'nickname', 'avatar']
            }]
        });
      rows=rows.map(item=>{
          return {
              id:item.user_follow.id,
              name:item.user_follow.username||item.user_follow.nickname,
              avatar:item.user_follow.avatar
          }
      })
      // 返回数据
      ctx.apiSuccess(rows)
    }

    // 我的粉丝列表
    async fens() {
        const { ctx, service, app } = this;
        let currentUser = ctx.authUser;

        let rows = await ctx.page(app.model.Follow, {
            follow_id: currentUser.id
        }, {
            include: [{
                model: app.model.User,
                as: "user_fen",
                attributes: ['id', 'username', 'nickname', 'avatar']
            }]
        });

        rows = rows.map(item => {
            return {
                id: item.user_fen.id,
                name: item.user_fen.nickname || item.user_fen.username,
                avatar: item.user_fen.avatar
            }
        });

        ctx.apiSuccess(rows);
    }
}

module.exports = UserController;
